#include <stdafx.h>
#include "ScriptEditorRegisters.h"

namespace Lit
{
	namespace Editor
	{
		ScriptRegisters::ScriptRegisters( QWidget * parent )
			: QDialog( parent )
		{ 
			ui.setupUi( this ); 

			setupGlobalVariablesUi();
			setupGlobalFunctionsUi();
			setupObjectsUi();
		}
		ScriptRegisters::~ScriptRegisters()
		{}

		void ScriptRegisters::setupGlobalVariablesUi()
		{
			ui.globalVarsTable->clear();
			ui.globalVarsTable->setColumnCount( 3 );
			ui.globalVarsTable->setColumnWidth( 0, 80 );
			ui.globalVarsTable->setColumnWidth( 1, 150 );
			ui.globalVarsTable->setHorizontalHeaderLabels( QStringList() << "Name" << "Type" << "Address" );
			ui.globalVarsTable->horizontalHeader()->setStretchLastSection( true );
		}
		void ScriptRegisters::setupGlobalFunctionsUi()
		{
			ui.globalFuncsTable->clear();
			ui.globalFuncsTable->setColumnCount( 2 );
			ui.globalFuncsTable->setColumnWidth( 0, 80 );
			ui.globalFuncsTable->setHorizontalHeaderLabels( QStringList() << "Name" << "Declaration" );
			ui.globalFuncsTable->horizontalHeader()->setStretchLastSection( true );
		}
		void ScriptRegisters::setupObjectsUi()
		{
			ui.objectsTree->clear();
			ui.objectsTree->setColumnCount( 2 );
			ui.objectsTree->setHeaderLabels( QStringList() << "Name" << "Declaration" );
		}
		
		void ScriptRegisters::updateGlobalVariablesUi( const ScriptEnginePtr & engine )
		{
			ui.globalVarsTable->clearContents();
			ui.globalVarsTable->setRowCount(0);
			ScriptEngine::Ptr pEngine(engine->data());
			for( size_t i=0; i<pEngine->GetGlobalPropertyCount(); i++ )
			{
				size_t id = ui.globalVarsTable->rowCount();
				const char *name;
				const char *nspace;
                int typeId;
                bool isConst;
				void * ptr;

				pEngine->GetGlobalPropertyByIndex(i, &name,&nspace, &typeId, &isConst, 0, &ptr, 0 );
				std::string typestr = pEngine->GetTypeDeclaration( typeId, true );

				ui.globalVarsTable->insertRow( id );
				ui.globalVarsTable->setItem( id, 0, new QTableWidgetItem( name ) );
				ui.globalVarsTable->setItem( id, 1, new QTableWidgetItem( typestr.c_str() ) );
				
				QTableWidgetItem *addrItm(new QTableWidgetItem( String((size_t)ptr).cstr() ));
				if( !isConst ) addrItm->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
				ui.globalVarsTable->setItem( id, 2, addrItm );
			}
		}
		void ScriptRegisters::updateGlobalFunctionsUi( const ScriptEnginePtr & engine )
		{
			ui.globalFuncsTable->clearContents();
			ui.globalFuncsTable->setRowCount(0);
			ScriptEngine::Ptr pEngine(engine->data());
			for( size_t i=0; i<pEngine->GetGlobalFunctionCount(); i++ )
			{
				ScriptFunctionPtr func( pEngine->GetGlobalFunctionByIndex( i ) );
				size_t id = ui.globalFuncsTable->rowCount();
				ui.globalFuncsTable->insertRow( id );
				ui.globalFuncsTable->setItem( id, 0, new QTableWidgetItem( func->GetName() ) );
				ui.globalFuncsTable->setItem( id, 1, new QTableWidgetItem( func->GetDeclaration(true, true) ) );
			}
		}
		void ScriptRegisters::updateObjectsUi( const ScriptEnginePtr & engine )
		{
			ui.objectsTree->clear();
			ScriptEngine::Ptr pEngine(engine->data());
			for( size_t i = 0; i<pEngine->GetObjectTypeCount(); i++ )
			{
				asIObjectType * type = pEngine->GetObjectTypeByIndex( i );
				std::string typeDecl = pEngine->GetTypeDeclaration(type->GetTypeId());

				QTreeWidgetItem * obj = createObjectNode( type->GetName() );
				QTreeWidgetItem * meth = new QTreeWidgetItem( obj, QStringList() << "Methods" );
				//createObjectMethod( obj, type->GetPropertyDeclaration( type->GetTypeId() ), typeDecl );
				for( size_t j=0; j<type->GetMethodCount(); j ++ )
				{
					ScriptFunctionPtr func(type->GetMethodByIndex( j ));
					createObjectMethod( meth, func->GetName(), func->GetDeclaration( true, true ) );
				}
				
				QTreeWidgetItem * vars = new QTreeWidgetItem( obj, QStringList() << "Variables" );
				for( size_t j=0; j<type->GetPropertyCount(); j ++ )
				{
					const char *name;
					const char *nspace;
					int typeId;
					int offset;
					bool isRef, isPrivate;
					void * ptr;
					assert( type->GetProperty(j, &name, &typeId, &isPrivate, &offset, &isRef) >= 0 );
					createObjectProperty( vars, pEngine->GetTypeDeclaration( typeId, true ), name );
				}
			}
		}
		void ScriptRegisters::updateUi( const ScriptEnginePtr & engine )
		{
			updateGlobalVariablesUi( engine );
			updateGlobalFunctionsUi( engine );
			updateObjectsUi( engine );
		}
		int ScriptRegisters::exec( const ScriptEnginePtr & engine )
		{
			updateUi(engine);
			return QDialog::exec();
		}
		QTreeWidgetItem * ScriptRegisters::createObjectNode( const std::string &obj_type )
		{
			QTreeWidgetItem * ret = new QTreeWidgetItem( ui.objectsTree, QStringList() << QString(obj_type.c_str()) );
			ui.objectsTree->addTopLevelItem( ret );
			return ret;
		}
		QTreeWidgetItem * ScriptRegisters::createObjectMethod( QTreeWidgetItem * obj, const std::string & name, const std::string &declaration )
		{
			QTreeWidgetItem * ret = new QTreeWidgetItem( obj, QStringList() << QString(name.c_str()) << QString(declaration.c_str()) );
			obj->addChild( ret );
			return ret;
		}
		QTreeWidgetItem * ScriptRegisters::createObjectProperty( QTreeWidgetItem * obj, const std::string & type, const std::string &name )
		{
			QTreeWidgetItem * ret = new QTreeWidgetItem( obj, QStringList() << QString(type.c_str()) << QString(name.c_str()) );
			obj->addChild( ret );
			return ret;
		}
	};
};